package cn.rengy.web.framework.jwt;

import java.nio.charset.StandardCharsets;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.time.Duration;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.crypto.KeyGenerator;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.lang.Editor;
import cn.hutool.core.map.MapUtil;
import cn.rengy.tool.core.util._BeanUtils;
import cn.rengy.web.framework.principal.Identity;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.impl.DefaultClaims;

public class JwtService {
	private static Logger logger = LoggerFactory.getLogger(JwtService.class);
	private static Key 密钥;
	//private static int 有效期=60*60*1000;//token有效期60*60*1000
	//@Value("${jwt.secret}")
    private static String secret="2021";
    //创建时把clientId映射到aud
    private static Map<String,String> fieldMapping=new HashMap<String,String>(1,1);
    //反转
    private static Map<String,String> reversedFieldMapping;
	static {
		密钥 =generatorKey();
		fieldMapping.put("clientId", "aud");
		reversedFieldMapping=MapUtil.reverse(fieldMapping);
	}
	/*static {
		String SECRET_KEY="de98550ef004da097283a6b3b266c1db440223ebeb0db42c4fea026870c6b71f";
		byte keyBytes []=null;
		try {
			keyBytes=Hex.decodeHex(SECRET_KEY);
		} catch (DecoderException e) {
			logger.error(e.getMessage());
		}
		密钥 = Keys.hmacShaKeyFor(keyBytes);
	}*/
	/*public static Key getKey() {
		return 密钥;
	}*/
	
	public static String createToken(Identity identity,Duration timeout) {
		//String jti=RandomStringUtils.randomAlphanumeric(32);
		//String sub=AES.encryptHex(userid.toString(), GlobalSystemKey.key);
		//String sub=identity.getName();
		DefaultClaims defaultClaims=new DefaultClaims();
		defaultClaims.put("class", identity.getClass().getName());
		//defaultClaims.putAll(_BeanUtils.bean2Map(identity));
		//defaultClaims.remove("name");
		//defaultClaims.remove("clientId");
		BeanUtil.beanToMap(identity, defaultClaims, false, new Editor<String>() {
			@Override
			public String edit(String key){
				String value=fieldMapping.get(key);
				return value==null ? key : value;
			}
		});
		Long currentTimeMillis = System.currentTimeMillis();
		defaultClaims
		//.setId(jti)
		//.setAudience(identity.getClientId())
		.setIssuedAt(new Date(currentTimeMillis))//签发时间
		.setExpiration(new Date(currentTimeMillis+timeout.toMillis()));//过期时间
		
		return JwtUtils.create(defaultClaims, 密钥);
	}
	/*public static String createRefreshToken(Identity identity,Duration timeout) {
		String token=RandomStringUtils.randomAlphanumeric(32);
		return token;
	}*/
	
	
	
	public static Identity parseToken(String jwt) {
		Claims claims=JwtUtils.verify(jwt, 密钥);
		String className=(String)claims.get("class");
		Identity identity=_BeanUtils.createInstance(className,Identity.class);
		
		CopyOptions copyOptions=CopyOptions.create()
				.setFieldMapping(reversedFieldMapping);
		return BeanUtil.fillBeanWithMap(claims, identity, copyOptions);
	}
	
	
	private static Key generatorKey() {
		KeyGenerator kgen;
		try {
			kgen = KeyGenerator.getInstance("HmacSHA256");
			SecureRandom secureRandom=SecureRandom.getInstance("SHA1PRNG");
			secureRandom.setSeed(secret.getBytes(StandardCharsets.UTF_8));
			kgen.init(256, secureRandom);
			return kgen.generateKey();
		} catch (NoSuchAlgorithmException e) {
			logger.error("NoSuchAlgorithmException");
		}
		return null;
	}
	
	
	
	
	/*@SuppressWarnings("unused")
	private void generateSecretKey() throws NoSuchAlgorithmException {
		MD2 
		MD5 
		SHA-1
		 SHA-224
		 SHA-256
		 SHA-384
		 SHA-512
		MessageDigest md= MessageDigest.getInstance("SHA-256");
		md.update("distribution-catering+www.uniontrip.com".getBytes());
		byte by[]=md.digest();
		String s=Hex.encodeHexString(by);
		//de98550ef004da097283a6b3b266c1db440223ebeb0db42c4fea026870c6b71f
		//common 工具类
		//String s=DigestUtils.sha256Hex("distribution-catering+www.uniontrip.com");
		String b=Base64.encodeBase64String(by);
	}*/
	/*public static void main(String args[]) {
		//String s=DigestUtils.sha256Hex("distribution-catering+www.uniontrip.com"); 
		//System.out.println(s);
		String className=LocalIdentity.class.getName();
		System.out.println(className);
		Identity identity=_BeanUtils.createInstance(className,Identity.class);
		identity.setUserid(1L);
		System.out.println(identity);
		
		LocalIdentity localIdentity=new LocalIdentity();
		localIdentity.setUlid(10l);
		localIdentity.setUserid(20l);
		Map<String, Object> map=_BeanUtils.bean2Map(localIdentity);
		System.out.println(map);
		
		_BeanUtils.map2Bean(map, identity);
		System.out.println(identity);
		
		String token=createToken(localIdentity,Duration.ofDays(1));
		System.out.println(token);
	}*/
}
